﻿/*
  File: CRenderer.h
 
  Leírás:	a renderelést végző egyke osztály. A resource managertől kapott vektorokon iterálva rajzolja ki a megjelenítendő objektumokat. Kezeli az .fx fileokat és paramétereit.

  Szerző: SevN, Sipos Csaba


*/

#ifndef __CRENDERER_H__
#define __CRENDERER_H__

#include <d3dx9.h>
#include "..\GUI\CGUIObject.h"
#include "..\Util\Utilities.h"
#include "CDevice.h"
#include "CTimer.h"
#include "CFramePSecond.h"
#include "..\Includes\ICamera.h"
#include "..\Content\CCamera.h"
#include "..\Content\IRenderable.h"
#include "..\Content\CPrimitive.h"
#include <vector>
#include "..\Content\CBaseMesh.h"
#include "..\Content\CSkyBox.h"
#include "..\Content\\CAnimatedMesh.h"

#define PRIMITIVEFVF (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX0)

namespace Engine
{

  struct Material
  {
	  D3DXCOLOR ambientMat;
	  D3DXCOLOR diffuseMat;
	  D3DXCOLOR specularMat;
    float	specularPower;
  };

	class CRenderer
	{
	public:

    //egyke megsemmisítése
    static void destroy();

		static CRenderer * getInstance();

    //skybox és bufferek felszabadítása
		void clean();

    //minden kirajzolása
		void render();

    //primitiveket kirajzoló vertex és index buffer újraépítése
    void rebuildBuffers();

    // projekciós mátrix igazítása a felbontáshoz
    void updateMatProj();

    // kamera beállítása
 		void setCamera(Content::CCamera *);

    // primitive listájának beállítása, ezek kerülnek megjelenítésre
    void setPrimitiveQueue(std::vector<Content::CPrimitive*>* pPrim);

    // basemeshek listájának beállítása, ezek kerülnek megjelenítésre
    void setMeshQueue(std::vector<Content::CAnimatedMesh*>* pMeshes_in);

    // ablakok(GUI) listájának beállítása, ezek kerülnek megjelenítésre
    void setGUIQueue(std::vector<GUI::CGUIObject*>* pWindows_in);

    // égbolt cube textúrájának beállítása 
    void setSkyBoxTexture(std::string fname);

    // eszköz elveszett->felszabadítás
		void onLostDevice();

    // eszköz újra -> erőforrás újratöltés
		void onResetDevice();

	private:
		CRenderer();
		~CRenderer();

    // eszköz ellenörzése, elveszett-e
    void checkDevice();

    // projekciós mátrix újraszámolása (felbontás változása miatt kell)
    void buildMatProj();

    /*---SKYBOX---*/
      Content::CSkyBox* pSkyBox;

      // skybox rajzolásához szükséges effect paraméterek beállítása
      void initSkyEffect();

      // égbolt kirajzolása
      void renderSkyBox();

    /*---SKYBOX vége---*/

    /*---PRIMITIVE---*/
    

      IDirect3DVertexBuffer9* pPrimVBuffer;
      IDirect3DIndexBuffer9* pPrimIBuffer;
      IDirect3DVertexDeclaration9* pPrimVertexDecl;
      ID3DXEffect* pPrimEffect;

  		std::vector<Content::CPrimitive*>* pPrimitives;


      // primitivek vertex deklarációjának létrehozása
      void createPrimVertexDecl();

      // primitiveket tartalmazó vertex buffer újraépítése
      void buildPrimVertexBuffer();

      // primitiveket tartalmazó index buffer újraépítése
      void buildPrimIndexBuffer();

      // primitivek rajzolásához szükséges effect létrehozása(skybox is ez)
      void createPrimFX();

      // primitivek rajzolásához szükséges effect paraméterek beállítása
      void initPrimEffect();

      // primitivek rajzolása a lista alapján
      void renderPrimitives();

      // primitivek vertex és index bufferének felszabadítása
      void releaseBuffers();


    /*---PRIMITIVE vége---*/

    /*---BASEMESH---*/
      ID3DXEffect* pMeshEffect;

  		std::vector<Content::CAnimatedMesh*>* pMeshes;

      // basemeshek rajzolásához szükséges effect létrehozása
      void createMeshFX();

      // basemeshek rajzolásához szükséges effect paraméterek beállítása
      void initMeshEffect();

      // basemeshek rajzolása a lista alapján
      void renderMeshes();

    /*---BASEMESH vége---*/

    /*---GUI---*/
      //GUI elemek listája
		  std::vector<GUI::CGUIObject*>* pGUIObjects;

      //GUI kirajzolása
      void renderGUI();
    /*---GUI vége---*/

    int numPrimVertices;
    int numPrimIndices;
    int numPrimTriangles;
    struct Material primMat;

		static CRenderer* pInstance;
    bool deviceLost;
    int screenHeight,screenWidth;

		IDirect3DDevice9* pD3DDevice;
    CDevice* pDevice;
		//frame per másodperc
		CTimer* pTimer;
		CFramePSecond  *fps;
		//jelenlegi camera
		Content::CCamera * pCamera;
    


	  D3DXHANDLE  hTech;
	  D3DXHANDLE  hWVP;
	  D3DXHANDLE  hViewProj;
	  D3DXHANDLE  hWorld;
	  D3DXHANDLE  hAmbientMaterialColor;
	  D3DXHANDLE  hDiffuseMaterialColor;
	  D3DXHANDLE  hSpecularMaterialColor;
	  D3DXHANDLE 	hLightColor;
	  D3DXHANDLE 	hLightPos;
	  D3DXHANDLE 	hSpecularPower;
	  D3DXHANDLE 	hCameraPos;
	  D3DXHANDLE 	hTex0;
	  D3DXHANDLE 	hCubeTex;
	  D3DXHANDLE 	hDT;

  	D3DXCOLOR lightColor;
  	D3DXVECTOR3 lightPos;

		//renderelendő elemeket tartalmazó lista
    D3DXMATRIX matProj;
	};
}
#endif